package legumes.client.ui.otherboxes;

import java.util.List;

import legumes.client.evt.customer.CustomerStoreSelectionChangedEvent;
import legumes.client.evt.main.UserConnectedEvent;
import legumes.client.evt.main.UserConnectedEventHandler;
import legumes.client.evt.main.UserDisconnectedEvent;
import legumes.client.evt.main.UserDisconnectedEventHandler;
import legumes.client.evt.manager.EventBusManager;
import legumes.client.evt.store.StoreRemovedEvent;
import legumes.client.resources.PNResources;
import legumes.client.services.callbacks.AddStoreCallback;
import legumes.client.services.callbacks.IsStoreNameExistsCallback;
import legumes.client.services.callbacks.RemoveStoreCallback;
import legumes.client.services.util.rpc.RPCCallSequencer;
import legumes.client.ui.widgets.form.item.StoreSelectItem;
import legumes.shared.domain.Store;

import com.smartgwt.client.types.Alignment;
import com.smartgwt.client.types.VerticalAlignment;
import com.smartgwt.client.util.BooleanCallback;
import com.smartgwt.client.util.SC;
import com.smartgwt.client.util.ValueCallback;
import com.smartgwt.client.widgets.ImgButton;
import com.smartgwt.client.widgets.Window;
import com.smartgwt.client.widgets.events.ClickEvent;
import com.smartgwt.client.widgets.events.ClickHandler;
import com.smartgwt.client.widgets.form.DynamicForm;
import com.smartgwt.client.widgets.form.fields.events.ChangedEvent;
import com.smartgwt.client.widgets.form.fields.events.ChangedHandler;
import com.smartgwt.client.widgets.layout.HLayout;

public class CustomerStoresBoxPanel extends Window {
	
	private HLayout mainHLayout;
	private ImgButton addStoreBtn;
	private ImgButton editStoreBtn;
	private ImgButton delStoreBtn;
	private StoreSelectItem storeSelectItem;
	private String userId;
	
	public CustomerStoresBoxPanel() {
		super();
		setWidth100();
		setHeight(85);
		setMargin(5);
		
		setTitle("<img src=\"" + PNResources.INSTANCE.storeIcon().getURL() + "\" />&nbsp;Mes magasins");
		
		setShowCloseButton(false);
        setShowMinimizeButton(true);
		setCanDrag(false);
		setCanDragReposition(false);
		
		int imgButtonSize = 16;
		addStoreBtn = new ImgButton();
		addStoreBtn.setSize(imgButtonSize);
		addStoreBtn.setShowRollOver(false);  
		addStoreBtn.setSrc(PNResources.INSTANCE.addIcon().getURL());
		addStoreBtn.setTooltip("Créer un nouveau magasin...");
		addStoreBtn.addClickHandler(new ClickHandler() {
			
			@Override
			public void onClick(ClickEvent event) {
				onAddStoreAction(storeSelectItem.getSelectedStore());
			}
		});
		
		editStoreBtn = new ImgButton();
		editStoreBtn.setSize(imgButtonSize);
		editStoreBtn.setShowRollOver(false);
		editStoreBtn.setShowSelectedIcon(false);
		editStoreBtn.setShowDownIcon(false);
		editStoreBtn.setShowFocusedIcon(false);
		editStoreBtn.setShowDisabledIcon(false);
		editStoreBtn.setSrc(PNResources.INSTANCE.editIcon().getURL());
		editStoreBtn.setTooltip("Modifier le magasin sélectionné...");
		editStoreBtn.addClickHandler(new ClickHandler() {
			
			@Override
			public void onClick(ClickEvent event) {
				onEditStoreAction(storeSelectItem.getSelectedStore());
			}
		});

		delStoreBtn = new ImgButton();
		delStoreBtn.setSize(imgButtonSize);
		delStoreBtn.setShowRollOver(false);  
		delStoreBtn.setSrc(PNResources.INSTANCE.deleteIcon().getURL());
		delStoreBtn.setTooltip("Supprimer le magasin sélectionné...");
		delStoreBtn.addClickHandler(new ClickHandler() {
			
			@Override
			public void onClick(ClickEvent event) {
				onDelStoreAction(storeSelectItem.getSelectedStore());
			}
		});

		storeSelectItem = new StoreSelectItem(){

			@Override
			protected void onStoreListChanged(List<Store> storeList_,
					String storeIdToSelect_) {
				super.onStoreListChanged(storeList_, storeIdToSelect_);
				if(storeList_!=null && storeList_.size()==1){
					onEditStoreAction(storeList_.get(0));
				}
			}
			
		};
		storeSelectItem.addChangedHandler(new ChangedHandler() {
			
			@Override
			public void onChanged(ChangedEvent event) {
				onStoreSelectionChanged();
			}
		});
		DynamicForm df = new DynamicForm();
		df.setFields(storeSelectItem);
		
		
		mainHLayout = new HLayout();
		mainHLayout.setWidth100();
		mainHLayout.setHeight100();
		mainHLayout.setMembersMargin(5);
		mainHLayout.setMargin(10);
		mainHLayout.setAlign(VerticalAlignment.CENTER);
		mainHLayout.setAlign(Alignment.CENTER);
		mainHLayout.setMembers(df, addStoreBtn, editStoreBtn, delStoreBtn);
		
		addItem(mainHLayout);
		
		bind();
	}

	protected void onAddStoreAction(Store selectedStore) {
		createNewStore();
	}
	
	private void createNewStore(){
		SC.askforValue("Nouveau magasin", 
				"Saisir le nom de votre magasin <i>(Exemple : Les bons produits du terroir)</i> : ", 
				new ValueCallback() {
					
					@Override
					public void execute(final String value) {
						if( value != null && value.trim().length()>0){
							//Check store name do not already exists
							RPCCallSequencer callSequencer = new RPCCallSequencer();
							final IsStoreNameExistsCallback checkStoreNameCallback = new IsStoreNameExistsCallback(value);
							callSequencer.addCall(checkStoreNameCallback);
							callSequencer.addRunnable(new Runnable() {
								public void run() {
									if( checkStoreNameCallback.isStoreExists() ){
										SC.say("Nom déjà existant", "Le nom de magasin '" + value + "' existe déjà. Veuillez saisir un nouveau nom.", new BooleanCallback() {
											
											@Override
											public void execute(Boolean value) {
												createNewStore();
											}
										});
									} else {
										createNewStore(value);
									}
								}
							});
							callSequencer.callSequence();
						}
					}
				});
	}
	
	private void createNewStore(final String storeName_){
		RPCCallSequencer callSequencer = new RPCCallSequencer();
		Store stToCreate = new Store();
		//stToCreate ID is created on the serveur
		stToCreate.setCustomerId(userId);
		stToCreate.setOpened(false);
		stToCreate.setStoreName(storeName_);
		stToCreate.setMessage("");
		
		final AddStoreCallback addStoreCallback = new AddStoreCallback(stToCreate);
		callSequencer.addCall(addStoreCallback);
		callSequencer.addRunnable(new Runnable() {
			
			@Override
			public void run() {
				Store addedStore = addStoreCallback.getAddedStore();
				if(addedStore!=null){
					updateStoreList(storeName_);
					onEditStoreAction(addedStore);
				}
			}
		});
		callSequencer.callSequence();
	}
	
	protected void onDelStoreAction(final Store selectedStore) {
		if(selectedStore!=null){
			SC.confirm("Suppression du magasin", 
					"Etes vous sur de vouloir supprimer le magasin '" + selectedStore.getStoreName() + "', " +
					"ainsi que tout son historique de produits et de commandes ?", 
					new BooleanCallback() {
						
						@Override
						public void execute(Boolean value) {
							if(value){
								RPCCallSequencer callSequencer = new RPCCallSequencer();
								final RemoveStoreCallback removeStoreCallback = new RemoveStoreCallback(selectedStore);
								callSequencer.addCall(removeStoreCallback);
								callSequencer.addRunnable(new Runnable() {
									public void run() {
										if(removeStoreCallback.isRemovedState()){
											updateStoreList();
											EventBusManager.getInstance().getEventBus().fireEvent(
													new StoreRemovedEvent(selectedStore)
											);
										}
									}
								});
								callSequencer.callSequence();
							}
						}
					} );
		}
	}

	protected void onEditStoreAction(Store selectedStore) {
		if(selectedStore!=null){
			EventBusManager.getInstance().getEventBus().fireEvent(
					new CustomerStoreSelectionChangedEvent(selectedStore)
			);
		}
	}
	
	protected void onStoreSelectionChanged() {
		onEditStoreAction(storeSelectItem.getSelectedStore());
	}

	private void bind(){
		EventBusManager.getInstance().getEventBus().addHandler(
				UserConnectedEvent.TYPE, 
				new UserConnectedEventHandler(){

					@Override
					public void onUserConnected(UserConnectedEvent event) {
						CustomerStoresBoxPanel.this.onUserConnected( event.getCustomerDTO().getEmail() );
					}
				});
		
		EventBusManager.getInstance().getEventBus().addHandler(
				UserDisconnectedEvent.TYPE, 
				new UserDisconnectedEventHandler(){

					@Override
					public void onUserDisconnected(UserDisconnectedEvent event) {
						CustomerStoresBoxPanel.this.onUserDisconnected( event.getCustomerDTO().getEmail() );
					}

				});
	}
	
	private void onUserDisconnected(String userId_){
		userId = null;
		setVisible(false);
	}
	
	private void onUserConnected(String userId_){
		userId = userId_;
		setVisible(true);
		updateStoreList();
	}
	
	private void updateStoreList(){
		updateStoreList(null);
	}
	
	private void updateStoreList(String storeIdToSelect_){
		storeSelectItem.initData(userId, storeIdToSelect_);
	}
}
